package cn.ctodb.commons.pool;

import java.util.List;
import java.util.Vector;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.TimeUnit;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public abstract class ObjectPool<T extends Object> {
	private Logger logger = LoggerFactory.getLogger(getClass());
	// 连接池配置属性
	private volatile boolean isActive = false; // 连接池活动状态
	protected volatile int activeCount = 0;
	protected volatile int maxTotleCount = 5;
	protected volatile int minTotleCount = 2;
	protected volatile int minFreeCount = 2;
	protected volatile int lifecycle = 5 * 60 * 1000;

	// 空闲连接
	private volatile LinkedBlockingQueue<T> freeObject = new LinkedBlockingQueue<>();
	// 活动连接
	private volatile List<T> activeObject = new Vector<T>();

	// 初始化
	public void init() {
		for (int i = 0; i < minTotleCount; i++) {
			_create();
		}
		isActive = true;
		new Free().start();
		new Kill().start();
	}

	private synchronized void _create() {
		if (freeObject.size() + activeObject.size() >= maxTotleCount) {
			logger.error("连接数已满");
			return;
		}
		if (freeObject.size() >= minFreeCount) {
			return;
		}
		freeObject.add(create());
	}

	protected abstract T create();

	// 获得连接
	public synchronized T get() {
		if (freeObject.size() == 0) {
			_create();
		}
		try {
			T t = freeObject.poll(5, TimeUnit.SECONDS);
			activeObject.add(t);
			return t;
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
		return null;
	}

	// 释放连接
	public void release(T t) {
		activeObject.remove(t);
		try {
			freeObject.put(t);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
	};

	// 销毁连接池
	public void destroy() {
		isActive = false;
		new Thread() {
			public void run() {
				for (;;) {
					try {
						Thread.sleep(1000L);
					} catch (InterruptedException e) {
						e.printStackTrace();
					}
					for (T t : freeObject) {
						t.destroy();
						freeObject.remove(t);
					}
					if (freeObject.size() == 0)
						break;
				}
			}
		}.start();
	}

	// 连接池状态
	public boolean isActive() {
		return isActive;
	};

	// 定时检查连接池情况
	public void cheackPool() {

	};

	private class Free extends Thread {
		public void run() {
			for (;;) {
				try {
					lifecycle();
					_create();
					Thread.sleep(1000L);
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
			}
		}
	}

	private class Kill extends Thread {
		public void run() {
			for (;;) {
				try {
					autokill();
					Thread.sleep(30000L);
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
			}
		}
	}

	private void autokill() {
		if (freeObject.size() > minFreeCount) {
			logger.info("autokill");
			T t = freeObject.poll();
			t.destroy();
		}
	}

	private void lifecycle() {
		for (T t : freeObject) {
			if (t.getCreateTime() + this.lifecycle < System.currentTimeMillis()) {
				logger.info("lifecycle overtime");
				freeObject.remove(t);
				t.destroy();
			}
		}
	}

}
